package top.lishuoboy.javaweb.a09el_jstl; /**
 * @author lishuoboy
 * @date 2022-01-07 00:52
 */

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Slf4j
@WebServlet(name = "FileDownloadServlet", value = "/FileDownloadServlet")
public class FileDownloadServlet extends HttpServlet {
    /**
     * 下载文件
     * http://localhost:8080/lishuoboy_javaweb_war_exploded/FileDownloadServlet?filename=生机.jpg
     * http://localhost:8080/lishuoboy_javaweb_war_exploded/FileDownloadServlet?filename=生机.zip
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();

        // 1 从请求参数获取要下载的文件名，写死
        String downloadFileName = req.getParameter("filename");
        log.info(downloadFileName);

        // 2.1 【必须】告诉客户端收到的数据是用于下载使用(通过响应头)，防止图片、html直接展示。并告诉客户端下载的文件名字
        resp.setHeader("content-Disposition", "attachment;filename=" + URLUtil.encode(downloadFileName));

        // 2.2 【推荐】还可以告诉客户端返回的数据类型(通过响应头)，可以不用设置
        // 注意，过滤器可能过滤器已经设置了ContentType
        String mimeType = servletContext.getMimeType(downloadFileName);
        log.info(mimeType);
        // 以下两行等价，二选一
        resp.setContentType(mimeType);
//        resp.setHeader("content-type", mimeType);
        // 写死为 application/octet-stream，非图片、pdf可直接预览的格式也会直接下载
//        resp.setContentType("application/octet-stream");

        // 2.3 【推荐】还可以告诉客户端返回的数据长度(通过响应头)，可以不用设置
        File file = new File(servletContext.getResource("WEB-INF/classes/file/" + downloadFileName).getFile());
        log.info("file.length()=={}", file.length());
        resp.addHeader("Content-Length", "" + file.length());

        // 3 【必须】把下载的文件内容回传给客户端
        InputStream is = servletContext.getResourceAsStream("WEB-INF/classes/file/" + downloadFileName); //获取响应的输出流
        OutputStream os = resp.getOutputStream();
        IoUtil.copy(is, os);
    }
}